package gwt.immunology.client.components;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.logical.shared.ShowRangeEvent;
import com.google.gwt.event.logical.shared.ShowRangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.datepicker.client.CalendarModel;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.user.datepicker.client.MonthSelector;

import static gwt.immunology.shared.utils.ImmunologyUtils.*;

public class MonthAndYearSelector extends MonthSelector {

    public ListBox monthsListBox;
    public ListBox yearsListBox;
    public int olderSelectedYear;
    public int olderSelectedMonth;

    private Grid grid;
    private CalendarModel model;
    private DatePickerEx datePicker;
    private int currentMonthIndex = Integer.valueOf(DateTimeFormat.getFormat("M").format(new Date())) - 1;
    private int currentSelectedYear;
    private int currentSelectedMonth;
    private DateTimeFormat dateFormatter = DateTimeFormat.getFormat(DD_MM_YYYY);

    private static final int MONTHS_IN_YEAR = 12;

    public void setModel(CalendarModel model) {
        this.model = model;
    }

    public void setPicker(DatePickerEx picker) {
        this.datePicker = picker;

        this.datePicker.addShowRangeHandler(new ShowRangeHandler<Date>() {
			
			@Override
			public void onShowRange(ShowRangeEvent<Date> event) {
				Date start = event.getStart();
		        Date end = event.getEnd();
		        Integer daysBetween = CalendarUtil.getDaysBetween(start, end);
		        Date currentDate = new Date();
		        for (int i = 0; i < daysBetween; i++) {
		            Date date = new Date(start.getTime());
		            Boolean enabled = true;
		            CalendarUtil.addDaysToDate(date, i);
                    String dateString = dateFormatter.format(date);
		            Date dateFormatted = dateFormatter.parse(dateString);
		            String currentDateString = dateFormatter.format(currentDate);
                    Date currentDateFormatted = dateFormatter.parse(currentDateString);
		            
		            if (dateFormatted.after(currentDateFormatted)) {
		                enabled = false;
		            }
		            datePicker.getCalendarView().setEnabledOnDate(enabled, date);
		        }
			}
		});
    }

    @Override
    protected void refresh() {
    }

    @Override
    protected void setup() {
        //setup months
        monthsListBox = new ListBox();
        List<String> months = Arrays.asList(LocaleInfo.getCurrentLocale().getDateTimeFormatInfo().monthsFullStandalone());
        for (String month : months) {
            monthsListBox.addItem(month);
        }
        monthsListBox.setSelectedIndex(currentMonthIndex);
        monthsListBox.setVisibleItemCount(1);
        olderSelectedMonth = currentMonthIndex;
        
        //setup years
        yearsListBox = new ListBox();
        int currentYear = Integer.valueOf(DateTimeFormat.getFormat("yyyy").format(new Date()));
        for (int i = 1900; i <= currentYear; i++) {
            yearsListBox.addItem(String.valueOf(i));
        }
        yearsListBox.setSelectedIndex(yearsListBox.getItemCount() - 1);
        yearsListBox.setVisibleItemCount(1);
        olderSelectedYear = Integer.valueOf(yearsListBox.getItemText(yearsListBox.getItemCount() - 1));
        
        //setup years handler
        yearsListBox.addChangeHandler(new ChangeHandler() {
            
            @Override
            public void onChange(ChangeEvent event) {
                currentSelectedYear = Integer.valueOf(yearsListBox.getItemText(yearsListBox.getSelectedIndex()));
                int yearsShiftNumber = olderSelectedYear - currentSelectedYear;
                addMonths(-(yearsShiftNumber * MONTHS_IN_YEAR));
                olderSelectedYear = currentSelectedYear;
            }
        });
        
        //setup months handler
        monthsListBox.addChangeHandler(new ChangeHandler() {
            
            @Override
            public void onChange(ChangeEvent event) {
              currentSelectedMonth = monthsListBox.getSelectedIndex();
              int monthsShiftNumber = olderSelectedMonth - currentSelectedMonth;
              addMonths(-(monthsShiftNumber));
              olderSelectedMonth = currentSelectedMonth;
            }
        });
        
        // Set up grid.
        grid = new Grid(1, 2);
        grid.setWidget(0, 0, monthsListBox);
        grid.setWidget(0, 1, yearsListBox);

        CellFormatter formatter = grid.getCellFormatter();
        formatter.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_RIGHT);
        formatter.setHorizontalAlignment(0, 1, HasHorizontalAlignment.ALIGN_LEFT);
        grid.setStyleName("datePickerMonthSelector");
        initWidget(grid);
    }

    public void addMonths(int numMonths) {
        model.shiftCurrentMonth(numMonths);
        datePicker.refreshComponents();
    }

}
